package cn.getech.data.development.controller;



import cn.getech.data.development.constant.DataDevelopmentBizExceptionEnum;
import cn.getech.data.development.constant.PermissTypeEnum;
import cn.getech.data.development.entity.*;
import cn.getech.data.development.model.dto.TableInfoDto;
import cn.getech.data.development.model.vo.RoleConfigVO;
import cn.getech.data.development.service.IDataPermissionParamService;
import cn.getech.data.development.service.ITableFieldRulesService;
import cn.getech.data.development.service.RangerDataService;
import cn.getech.data.development.service.TableInfoService;
import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.utils.R;
import cn.getech.data.intelligence.common.utils.TypeFormatUtils;
import cn.getech.system.center.annotation.SysLog;
import cn.getech.system.center.constant.OperationModulesEnum;
import cn.getech.system.center.constant.OperationTypeEnum;
import cn.getech.system.center.constant.module.ModuleEnum;
import cn.getech.system.center.entity.RoleDataPermissionConfig;
import cn.getech.system.center.entity.RoleRowDataPermissionConfig;
import cn.getech.system.center.model.dto.RoleDataPermissionDto;
import cn.getech.system.center.model.dto.RoleRowDataPermissionDto;
import cn.getech.system.center.service.IRoleDataPermissionConfigService;
import cn.getech.system.center.service.IRoleRowDataPermissionConfigService;
import cn.getech.system.center.service.SysUserRoleService;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 角色数据权限配置 前端控制器
 * </p>
 *
 * @author nxy
 * @since 2019-12-18
 */
@RestController
@RequestMapping("/bdp/roleDataPermissionConfig")
public class RoleDataPermissionConfigController {
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private IRoleDataPermissionConfigService roleDataPermissionConfigService;
    @Autowired
    private IDataPermissionParamService dataPermissionParamService;
    @Autowired
    private TableInfoService tableInfoService;
    @Autowired
    private ITableFieldRulesService tableFieldRulesService;
    @Autowired
    private IRoleRowDataPermissionConfigService roleRowDataPermissionConfigService;

    @Autowired
    private RangerDataService rangerDataService;

    @ApiOperation("查看角色的数据访问权限")
    @PostMapping("/dataRight")
    @SysLog(value = "角色管理页面查看角色的数据访问权限", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.AUTH_MANAGER_MODULE_CODE)
    public R getDataRight(@RequestBody Map<String, Object> map){
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid)){
            Long rid = Long.valueOf((Integer)map.get("roleId"));
            // 查询角色权限及各种权限信息
            RoleDataPermissionDto roleDataPermissionConfig = roleDataPermissionConfigService.queryRoleDataPermissionDataByRoleId(rid);
            List<DataPermissionParam> dbDataPermissionParamList = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.DB_TYPE.getPermissType()));
            List<DataPermissionParam> tableDataPermissionParamList = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.TABLE_TYPE.getPermissType()));
            List<DataPermissionParam> fieldDataPermissionParamList = dataPermissionParamService.list(new QueryWrapper<DataPermissionParam>().
                    eq("permiss_type", PermissTypeEnum.FIELD_TYPE.getPermissType()));

            //无配置时默认用全局配置
            if (roleDataPermissionConfig == null){
                roleDataPermissionConfig = new RoleDataPermissionDto();
            }
            if (roleDataPermissionConfig.getTableLevelIds() == null){
                roleDataPermissionConfig.setTableLevelIds("");
            }
            if (roleDataPermissionConfig.getColoumLevelIds() == null){
                roleDataPermissionConfig.setColoumLevelIds("");
            }
            if (roleDataPermissionConfig.getDbIds() == null){
                roleDataPermissionConfig.setDbIds("");
            }

            // 关联行规则信息
            List<RoleRowDataPermissionDto> allRowDataPermission = roleDataPermissionConfig.getAllRowDataPermission();
            List<RoleRowDataPermissionDto> returnAllRowDataPermission = new LinkedList<>();
            if (allRowDataPermission != null){
                for (int i = 0; i < allRowDataPermission.size(); i++) {
                    RoleRowDataPermissionDto rowDataPermissionDto = allRowDataPermission.get(i);
                    TableInfo tableInfo = tableInfoService.getById(rowDataPermissionDto.getTableId());
                    TableFieldRules tableFieldRule = tableFieldRulesService.getById(rowDataPermissionDto.getTableFieldRulesId());
                    rowDataPermissionDto.setTable(tableInfo.getTableName());
                    rowDataPermissionDto.setTableAlias(tableInfo.getTableAlias());
                    if(tableFieldRule != null) {
                        rowDataPermissionDto.setRuleDesc(tableFieldRule.getRuleDesc());
                        rowDataPermissionDto.setRowParamId(tableFieldRule.getRowParamId());
                    }
                    rowDataPermissionDto.setDbName(tableInfo.getDbName());

                    returnAllRowDataPermission.add(rowDataPermissionDto);
                }
            }
            JSONObject roleRight = JSONObject.parseObject(JSONObject.toJSONString(roleDataPermissionConfig));
            roleRight.put("tableLevelIds", TypeFormatUtils.str2IntList(roleRight.getString("tableLevelIds")));
            roleRight.put("coloumLevelIds", TypeFormatUtils.str2IntList(roleRight.getString("coloumLevelIds")));
            if (roleDataPermissionConfig.getDbIds() != null){
                roleRight.put("dbIds", TypeFormatUtils.str2IntList(roleRight.getString("dbIds")));
            }

            //所有表名及其id
            List<TableInfo> allTables = tableInfoService.list();
            JSONObject tables = new JSONObject();
            for (TableInfo tableInfo : allTables){
                TableInfoDto tableInfoDto = new TableInfoDto();
                List<TableInfoDto> dbTables = new LinkedList<>();
                Set<String> keySet = tables.keySet();
                String dbName = tableInfo.getDbName();
                tableInfoDto.setId(tableInfo.getId());
                tableInfoDto.setTableName(tableInfo.getTableName());
                tableInfoDto.setTableAlias(tableInfo.getTableAlias());
                if (keySet.contains(dbName)){
                    List tableList = tables.getJSONArray(dbName);
                    tableList.add(tableInfoDto);
                    tables.put(dbName, tableList);
                }else {
                    dbTables.add(tableInfoDto);
                    tables.put(dbName, dbTables);
                }
            }

            String[] defaultTableLevel = new String[]{"A","B","C","D","E"};
            String[] defaultFieldLevel = new String[]{"1","2","3","4","5"};

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("roleRight",roleRight);
            jsonObject.put("dbName",dbDataPermissionParamList);
            jsonObject.put("tableName",tableDataPermissionParamList);
            jsonObject.put("fieldName", fieldDataPermissionParamList);
            jsonObject.put("rowRule", returnAllRowDataPermission);
            jsonObject.put("tables", tables);
            jsonObject.put("defaultTableLevel",defaultTableLevel);
            jsonObject.put("defaultFieldLevel",defaultFieldLevel);
            return R.okWithData(jsonObject);
        }
        return R.ok();
    }


    @ApiOperation("关联行规则弹窗")
    @GetMapping("/tableRules/{tableId}")
    @SysLog(value = "角色管理页面关联行规则弹窗相关信息", type = OperationTypeEnum.SELECTCODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.AUTH_MANAGER_MODULE_CODE)
    public R getTableRules(@PathVariable("tableId") Integer tableId){
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid)){
            List<TableFieldRules> tableFieldRulesList = tableFieldRulesService.list(new QueryWrapper<TableFieldRules>().
                    eq("table_id", tableId));
            String dbName = tableInfoService.getById(tableId).getDbName();
            DataPermissionParam dataPermissionParam = dataPermissionParamService.getOne(new QueryWrapper<DataPermissionParam>().eq("permiss_name",dbName));
            Integer dbId = 0;
            if(dataPermissionParam != null){
                dbId = dataPermissionParam.getId();
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("rules", tableFieldRulesList);
            jsonObject.put("dbName", dbName);
            jsonObject.put("dbId", dbId);
            return R.okWithData(jsonObject);
        }
        return R.ok();
    }


    @ApiOperation("保存角色管理")
    @PostMapping("/save")
    @SysLog(value = "角色管理页面保存角色相关配置", type = OperationTypeEnum.ADDCODE, modulesType = OperationModulesEnum.SYSMODECODE,platformModuleType = ModuleEnum.AUTH_MANAGER_MODULE_CODE)
    @Transactional(rollbackFor = Exception.class)
    public R saveConfig(@RequestBody RoleConfigVO roleConfigVO){
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid)){
            RoleDataPermissionConfig roleDataPermissionConfig = new RoleDataPermissionConfig();
            roleDataPermissionConfig.setColoumLevelIds(TypeFormatUtils.list2Str(roleConfigVO.getColumnLevelIds()));
            roleDataPermissionConfig.setTableLevelIds(TypeFormatUtils.list2Str(roleConfigVO.getTableLevelIds()));
            roleDataPermissionConfig.setDbIds(TypeFormatUtils.list2Str(roleConfigVO.getDbIds()));
            roleDataPermissionConfig.setRoleId(Long.valueOf(roleConfigVO.getRoleId()));
            if(null != roleConfigVO.getId()){
                roleDataPermissionConfig.setId(roleConfigVO.getId());
            }
            roleDataPermissionConfigService.saveOrUpdate(roleDataPermissionConfig);

            //新增当前角色下的所有的用户
            rangerDataService.saveAllPolicy(roleConfigVO.getRoleId());

        }
        return R.ok();
    }


    @ApiOperation("保存关联行规则相关信息")
    @PostMapping("/saveRowRule")
    @SysLog(value = "保存关联行规则相关信息", type = OperationTypeEnum.ADDCODE, modulesType = OperationModulesEnum.BDPMODELCODE,platformModuleType = ModuleEnum.AUTH_MANAGER_MODULE_CODE)
    public R saveRowRule(@RequestBody RoleRowDataPermissionConfig roleRowDataPermissionConfig){
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid)){
            //验证当前角色和这个表是否配置过
            List<RoleRowDataPermissionConfig> list = roleRowDataPermissionConfigService.list(new QueryWrapper<RoleRowDataPermissionConfig>().eq("table_id", roleRowDataPermissionConfig.getTableId()).eq("role_data_permission_id", roleRowDataPermissionConfig.getRoleDataPermissionId()));
            if(CollectionUtil.isNotEmpty(list)){
                throw new RRException(DataDevelopmentBizExceptionEnum.TABLE_ROW_RILES_HAVE_EXIT.getMessage());
            }
            roleRowDataPermissionConfigService.save(roleRowDataPermissionConfig);
            //还得保存对应的行规则策略
            TableFieldRules tableFieldRules = tableFieldRulesService.getById(roleRowDataPermissionConfig.getTableFieldRulesId());
            if(null != tableFieldRules){
                rangerDataService.saveRangerPolicy(tableFieldRules.getTableId());
            }
        }
        return R.okWithData(roleRowDataPermissionConfig.getId());
    }

    @ApiOperation("删除关联行规则相关信息")
    @PostMapping("/delRowRule")
    @SysLog(value = "删除关联行规则相关信息", type = OperationTypeEnum.DELETECODE, modulesType = OperationModulesEnum.BDPMODELCODE,platformModuleType = ModuleEnum.AUTH_MANAGER_MODULE_CODE)
    public R delRowRule(@RequestBody Map<String, Object> map){
        Long uid = ShiroUtils.getUserId();
        if (sysUserRoleService.superAdmin(uid)){
            Integer id = Integer.parseInt(map.get("id").toString());
//            rangerDataService.deleteRangerPolicyByRoleRowDataPermissionConfigId(id);
            RoleRowDataPermissionConfig roleRowDataPermissionConfig = roleRowDataPermissionConfigService.getById(id);
            if(null != roleRowDataPermissionConfig){
                roleRowDataPermissionConfigService.removeById(id);
                //再修改这个行规则策略
                rangerDataService.saveRangerPolicy(roleRowDataPermissionConfig.getTableId());
            }
        }
        return R.ok();
    }

}

